// Copyright 2011 George Cook
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.



#import "BaseTest.h"
#import <GHUnit/GHUnit.h>
#import "InjectivePropertyValueDescription.h"
#import "Injective.h"
#import "InjectiveContextXMLFactory.h"
#import "InjectiveContainer.h"
#import "InjectivePropertyDescription.h"
#import "InjectiveObjectDescription.h"
#import "InjectiveDictionaryPropertyValueDescription.h"

@interface InjectiveDictionaryContainerMock : InjectiveContainer
{
}
@end

@implementation InjectiveDictionaryContainerMock
- (id) getObjectByPropertyDescription:(InjectivePropertyDescription *)propertyDescription
{
	return [propertyDescription.type isEqualToString:@"FunkyProvider" ] ? @"CORRECT" : @"CORRECT2";
}

@end



@interface InjectiveDictionaryPropertyValueDescriptionTest : BaseTest
{
	InjectiveContextXMLFactory *factory;
	InjectiveContainer *container;
}
@end


@implementation InjectiveDictionaryPropertyValueDescriptionTest
- (void)setUp
{
	factory = [[InjectiveContextXMLFactory alloc] init];
	container = [[InjectiveDictionaryContainerMock alloc] init];
}

- (void)tearDown
{
	[factory release], factory = nil;
	[container release], container = nil;
}


- (void)testRealValue
{
	//sanity check on the descriptions
	
	NSArray *descriptions = [factory processXMLFile:@"testDictionaryValue.xml"];
	GHAssertNotNil(descriptions, @"no descriptions were generated");
	InjectiveObjectDescription *description = [descriptions lastObject];
	GHAssertNotNil(description.propertyDescriptions, @"there were no property descriptions");
	GHAssertTrue(1 == description.propertyDescriptions.count, @"didn't create 1 property, created %d", description.propertyDescriptions.count);
	InjectivePropertyDescription *propertyDescription = [description.propertyDescriptions lastObject];
	GHAssertTrue([propertyDescription.type isEqualToString:@"Dictionary"],@"didn't detect correct type");
	GHAssertTrue([propertyDescription.propertyName isEqualToString:@"dictionaryValue"],@"didn't detect correct property name");
	InjectiveDictionaryPropertyValueDescription *dictionaryDescription = (InjectiveDictionaryPropertyValueDescription *)propertyDescription.value;
	GHAssertNotNil(dictionaryDescription,@"value wasn't set");
	GHAssertTrue(dictionaryDescription.class == [InjectiveDictionaryPropertyValueDescription class],@"was not an dictionary class");
	GHAssertTrue(3 == dictionaryDescription.valueDescriptionsByName.count, @"dictionary dind't have 3 elements had %d",
				 dictionaryDescription.valueDescriptionsByName.count);
	
	//now get the real value
	NSDictionary *realDictionaryValue = [dictionaryDescription realValueUsingContainer:container];
	GHAssertNotNil(realDictionaryValue,@"real value wasn't set");
	GHAssertTrue([realDictionaryValue isKindOfClass:NSDictionary.class],@"was not an dctionary class");
	GHAssertTrue(3 == realDictionaryValue.count, @"real array dind't have 3 elements had %d",
				 realDictionaryValue.count);
	
	
	//test the actual values
	
	NSNumber *integerElement = [realDictionaryValue objectForKey:@"numberValue"];
	GHAssertNotNil(integerElement,@"real value wasn't set for numbervalue object");
	GHAssertTrue([integerElement isKindOfClass:NSNumber.class],@"was not a NSNumber class");
	GHAssertTrue([integerElement isEqualToNumber:INJNINT(1)],@"string not correctly set");
	
	NSString *stringElement = [realDictionaryValue objectForKey:@"stringValue"];
	GHAssertNotNil(stringElement,@"real value wasn't set for stringValue element");
	GHAssertTrue([stringElement isKindOfClass:NSString.class],@"was not a string class");
	GHAssertTrue([stringElement isEqualToString:@"some text"],@"string not correctly set");
	
	NSString *funkyProvider = [realDictionaryValue objectForKey:@"funkyValue"];
	GHAssertNotNil(funkyProvider,@"class ref wasn't set for funky value element");
	GHAssertTrue([funkyProvider isKindOfClass:NSString.class],@"class ref was not looked up correctly");
	GHAssertTrue([funkyProvider isEqualToString:@"CORRECT"],@"class ref not correctly set");
}


@end
